package com.foo.common.base.service;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;

import com.foo.common.base.pojo.FooGenericSearch;
import com.foo.common.base.pojo.FooGenericSearchResult;
import com.foo.common.base.pojo.FooGenericTransactionModel;

public interface FooGenericService {

	/**
	 * Remove a persistent instance from the datastore. The argument may be an
	 * instance associated with the receiving <tt>Session</tt> or a transient
	 * instance with an identifier associated with existing persistent state.
	 * This operation cascades to associated instances if the association is
	 * mapped with {@code cascade="delete"}
	 * 
	 * @param object
	 *            the instance to be removed
	 */
	public void delete(Object object);

	public <T> Object load(Class<T> theClass, Serializable id);

	/**
	 * Remove a persistent instance from the datastore. The <b>object</b>
	 * argument may be an instance associated with the receiving
	 * <tt>Session</tt> or a transient instance with an identifier associated
	 * with existing persistent state. This operation cascades to associated
	 * instances if the association is mapped with {@code cascade="delete"}
	 * 
	 * @param entityName
	 *            The entity name for the instance to be removed.
	 * @param object
	 *            the instance to be removed
	 */
	public void delete(String entityName, Object object);

	/**
	 * <p>
	 * If the id of the entity is null or zero, add it to the datastore and
	 * assign it an id; otherwise, update the corresponding entity in the
	 * datastore with the properties of this entity. In either case the entity
	 * passed to this method will be attached to the session.
	 * 
	 * <p>
	 * If an entity to update is already attached to the session, this method
	 * will have no effect. If an entity to update has the same id as another
	 * instance already attached to the session, an error will be thrown.
	 * 
	 * @return <code>true</code> if create; <code>false</code> if update.
	 */
	public Serializable save(Object object);

	/**
	 * Returns a <code>SearchResult</code> object that includes both the list of
	 * results like <code>search()</code> and the total length like
	 * <code>count()</code>.
	 * 
	 * @param T
	 *            The result type is automatically determined by the context in
	 *            which the method is called.
	 */

	public FooGenericSearchResult searchAndCount(FooGenericSearch search);

	/**
	 * Flushes changes in the Hibernate session to the datastore.
	 */
	public void flush();

	public void doInTransaction(
			FooGenericTransactionModel fooGenericTransactionModel);

	public FooGenericSearchResult list(FooGenericSearch fooGenericSearch);

	public <T> List<T> list(String hql);

	public SessionFactory getSessionFactory();

	String logSummary();

	FooGenericSearchResult list(Query query);

	<T> T getObject(Class<T> metaClazz, String searchSql) throws Exception;
}
